<template>
  <div class="board-container">
    <!-- 头部悬浮 -->
    <div class="board-header-row">
      <div class="board-header-info">
        <span>实时看板号:</span>
        <span class="board-num">{{ num }}</span>
        <span>已加入人数:</span>
        <span class="board-joined">{{ boradList.length }}人</span>
        <span class="board-date">{{ nowDate }}</span>
      </div>
      <div class="dropdown">
        <button @click="toggleDropdown" class="dropdown-btn">
          选择展示项目
        </button>
        <div v-if="showDropdown" ref="dropdownRef" class="dropdown-menu">
          <label v-for="(option, index) in options" :key="index" class="dropdown-item">
            <input type="checkbox" v-model="option.checked" />
            {{ option.label }}
          </label>
        </div>
      </div>
    </div>
    <!-- 状态悬浮 -->
    <p class="board-status">
      <span class="board-online-wrap"> 当前在线人数: </span>
      <span class="board-online">{{ onlineStuNum }}</span>
      <span class="board-offline-wrap"> 离线人员: </span>
      <span class="board-offline-names">{{
        offlineStuNames ? offlineStuNames : "无"
        }}</span>
    </p>
    <div class="card-area-scroll" ref="scrollRef">
      <template v-if="isEffective">
        <template v-if="onlineList.length > 0">
          <div class="card">
            <div class="card-wrapper" v-for="(item, index) in onlineList" :key="index">
              <div class="card-item">
                <div class="card-row">
                  <span class="card-label card-name" :title="item.nickname">{{
                    item.nickname
                    }}</span>
                  <span class="card-value" v-if="showField('累计在线时长')" :title="`累计在线：${item.onlineTime}`">累计在线：{{
                    item.onlineTime }}</span>
                </div>
                <el-divider class="card-divider" />
                <div class="card-content">
                  <div class="card-row" v-if="showField('当前使用模块')">
                    <span class="card-label">当前使用:</span>
                    <span class="card-value" :title="item.moduleName">{{
                      item.moduleName
                      }}</span>
                  </div>
                  <div class="card-row" v-if="showField('当前学习知识点')">
                    <span class="card-label">知识点:</span>
                    <span class="card-value" :title="item.catalogName ? item.catalogName : '无'">{{ item.catalogName ?
                      item.catalogName : "无" }}</span>
                  </div>

                  <div v-if="showField('知识点掌握程度')" class="card-row">
                    <span class="card-label">掌握程度:</span>
                    <span class="card-value" :title="item.level ? item.level : '无'">{{ item.level ? item.level : "无"
                      }}</span>
                  </div>
                  <div v-if="showField('当前视频名称')" class="card-row">
                    <span class="card-label">视频:</span>
                    <span class="card-value" :title="item.videoName ? item.videoName : '无'">{{ item.videoName ?
                      item.videoName : "无" }}</span>
                  </div>
                  <div v-if="showField('当前视频观看进度')" class="card-row">
                    <span class="card-label">观看进度:</span>
                    <span class="card-value" :title="item.videoTotalTime
                        ? `${item.videoCurrentTime}/${item.videoTotalTime}`
                        : '无'
                      ">
                      {{
                        item.videoTotalTime
                          ? `${item.videoCurrentTime}/${item.videoTotalTime}`
                          : "无"
                      }}
                    </span>
                  </div>
                </div>
              </div>
            </div>
          </div>
        </template>
        <template v-else>
          <el-empty description="暂无在线数据" />
        </template>
      </template>
      <template v-else>
        <el-empty :description="tip" />
      </template>
    </div>
  </div>
</template>

<script setup>
import { ref, computed, onMounted, onUnmounted, nextTick } from "vue";
import { useRoute, useRouter } from "vue-router";
import { checkBoardNo, getRealTimeBoardList } from "@/api/index";
import dayjs from "dayjs";

// 字段选择相关
const showDropdown = ref(false);
const options = ref([
  { label: "累计在线时长", checked: true },
  { label: "当前使用模块", checked: true },
  { label: "当前学习知识点", checked: true },
  { label: "知识点掌握程度", checked: true },
  { label: "当前视频名称", checked: true },
  { label: "当前视频观看进度", checked: true },
]);
const toggleDropdown = () => {
  showDropdown.value = !showDropdown.value;
};
const dropdownRef = ref(null);
let handleClickOutside = null;
onMounted(() => {
  handleClickOutside = (event) => {
    if (
      !event.target.classList.contains("dropdown-btn") &&
      dropdownRef.value &&
      !dropdownRef.value.contains(event.target)
    ) {
      showDropdown.value = false;
    }
  };
  document.addEventListener("click", handleClickOutside);
});
onUnmounted(() => {
  document.removeEventListener("click", handleClickOutside);
});
const showField = (label) =>
  options.value.find((opt) => opt.label === label)?.checked;

const route = useRoute();
const { id } = route.params;
const num = ref(id);

const isEffective = ref(true);
const tip = ref("看板不存在");
const router = useRouter();
const nowDate = ref(dayjs().format("YYYY-MM-DD HH:mm:ss"));

const boradList = ref([]);
const onlineStuNum = computed(() => {
  return boradList.value.filter((item) => item.status == 0).length;
});
const offlineStuNames = computed(() => {
  return boradList.value
    .filter((item) => item.status == 1)
    .map((item) => item.nickname)
    .join("、");
});
const onlineList = computed(() =>
  boradList.value.filter((item) => item.status == 0)
);

function formatTime(totalSeconds) {
  const hours = Math.floor(totalSeconds / 3600);
  const remainingSeconds = totalSeconds % 3600;
  const minutes = Math.floor(remainingSeconds / 60);
  return `${hours}小时${minutes}分钟`;
}
function formatTimeHHMMSS(totalSeconds) {
  const hours = Math.floor(totalSeconds / 3600);
  const minutes = Math.floor((totalSeconds % 3600) / 60);
  const seconds = totalSeconds % 60;
  return `${hours > 0 ? String(hours).padStart(2, "0") + ":" : ""}${String(
    minutes
  ).padStart(2, "0")}:${String(seconds).padStart(2, "0")}`;
}

// 定时刷新相关
const refreshInterval = 10000; // 10秒
let refreshTimer = null;

const getList = async () => {
  try {
    const isNormal = await checkBoardNo({ board_id: id });
    if (isNormal) {
      isEffective.value = false;
      tip.value = isNormal;
      return;
    }
    isEffective.value = true;
    const res = await getRealTimeBoardList({ board_id: id });
    if (Array.isArray(res) && res.length > 0) {
      boradList.value = res.map((item) => {
        const jsonData = item.dataJson ? JSON.parse(item.dataJson) : {};
        return {
          nickname: item.nickname,
          status:
            item.status == 0
              ? dayjs(item.updateTime).isBefore(dayjs().subtract(1, "minute"))
                ? 1
                : 0
              : item.status,
          onlineTime: formatTime(Number(item.onlineTime)),
          moduleName: item.moduleName,
          catalogName: item.catalogName,
          useTime: formatTime(Number(item.useTime)),
          level: item.level,
          videoName: jsonData.videoName || "",
          videoCurrentTime: jsonData.progress
            ? Number(jsonData.progress.split("/")[0]) /
              Number(jsonData.progress.split("/")[1]) >=
              0.99
              ? formatTimeHHMMSS(Number(jsonData.progress.split("/")[1]))
              : formatTimeHHMMSS(Number(jsonData.progress.split("/")[0]))
            : "",
          videoTotalTime: jsonData.progress
            ? formatTimeHHMMSS(Number(jsonData.progress.split("/")[1]))
            : "",
        };
      });
    } else {
      boradList.value = [];
      // //伪造30条数据
      // boradList.value = Array.from({ length: 30 }, (_, index) => ({
      //   nickname: `学生${index + 1}`,
      //   status: index % 2 === 0 ? 0 : 1, // 偶数在线，奇数离线
      //   onlineTime: formatTime(3600 + index * 60), // 模拟在线时长
      //   moduleName: "模块" + (index % 3 + 1),
      //   catalogName: "知识点" + (index % 5 + 1),
      //   useTime: formatTime(1800 + index * 30), // 模拟使用时长
      //   level: "掌握程度" + (index % 4 + 1),
      //   videoName: `视频${index % 10 + 1}`,
      //   videoCurrentTime: formatTimeHHMMSS(300 + index * 10),
      //   videoTotalTime: formatTimeHHMMSS(600 + index * 20),
      // }));
    }
  } catch (error) {
    console.log(error);
    boradList.value = [];
  }
};

// 自动滚动相关
const scrollRef = ref(null);
const scrollSpeed = 1.2; // px/帧
let scrollDirection = "down"; // "down" or "up"
let scrollAnimationFrame = null;
let isScrolling = false;
let isPausedByUser = false;
let resumeTimer = null;
const resumeDelay = 5000; // 用户无操作5秒后恢复自动滚动

function hasScrollBar() {
  const el = scrollRef.value;
  if (!el) return false;
  return el.scrollHeight > el.clientHeight + 1;
}

const scrollStep = () => {
  if (!scrollRef.value) return;
  if (isPausedByUser) return;
  if (!hasScrollBar()) {
    isScrolling = false;
    return;
  }
  const el = scrollRef.value;
  const maxScrollTop = el.scrollHeight - el.clientHeight;
  if (scrollDirection === "down") {
    if (el.scrollTop < maxScrollTop - 1) {
      el.scrollTop = Math.min(el.scrollTop + scrollSpeed, maxScrollTop);
      scrollAnimationFrame = requestAnimationFrame(scrollStep);
    } else {
      el.scrollTop = maxScrollTop;
      scrollDirection = "up";
      isScrolling = false;
      setTimeout(() => {
        if (!isPausedByUser && hasScrollBar()) {
          startAutoScroll();
        }
      }, 500);
    }
  } else {
    if (el.scrollTop > 1) {
      el.scrollTop = Math.max(el.scrollTop - scrollSpeed, 0);
      scrollAnimationFrame = requestAnimationFrame(scrollStep);
    } else {
      el.scrollTop = 0;
      scrollDirection = "down";
      isScrolling = false;
      setTimeout(() => {
        if (!isPausedByUser && hasScrollBar()) {
          startAutoScroll();
        }
      }, 500);
    }
  }
};

const startAutoScroll = () => {
  if (isScrolling) return;
  isScrolling = true;
  scrollAnimationFrame = requestAnimationFrame(scrollStep);
};

const stopAutoScroll = () => {
  isScrolling = false;
  if (scrollAnimationFrame) {
    cancelAnimationFrame(scrollAnimationFrame);
    scrollAnimationFrame = null;
  }
};

// 用户操作相关
const pauseAutoScrollByUser = () => {
  if (!isPausedByUser) {
    isPausedByUser = true;
    stopAutoScroll();
  }
  if (resumeTimer) clearTimeout(resumeTimer);
  resumeTimer = setTimeout(() => {
    isPausedByUser = false;
    if (hasScrollBar()) startAutoScroll();
  }, resumeDelay);
};

const addUserPauseListeners = () => {
  const el = scrollRef.value;
  if (!el) return;
  el.addEventListener("mouseenter", pauseAutoScrollByUser);
  el.addEventListener("wheel", pauseAutoScrollByUser, { passive: true });
  el.addEventListener("touchstart", pauseAutoScrollByUser, { passive: true });
  el.addEventListener("mousedown", pauseAutoScrollByUser);
};
const removeUserPauseListeners = () => {
  const el = scrollRef.value;
  if (!el) return;
  el.removeEventListener("mouseenter", pauseAutoScrollByUser);
  el.removeEventListener("wheel", pauseAutoScrollByUser);
  el.removeEventListener("touchstart", pauseAutoScrollByUser);
  el.removeEventListener("mousedown", pauseAutoScrollByUser);
};

// 监听窗口变化，自动滚动自适应
const handleResize = () => {
  if (!isPausedByUser && hasScrollBar()) {
    startAutoScroll();
  } else {
    stopAutoScroll();
  }
};

onMounted(async () => {
  await getList();
  await nextTick();
  addUserPauseListeners();
  // 启动自动滚动（如果有滚动条）
  if (hasScrollBar()) startAutoScroll();
  window.addEventListener("resize", handleResize);
  // 启动定时刷新
  refreshTimer = setInterval(() => {
    getList();
  }, refreshInterval);
  setInterval(() => {
    nowDate.value = dayjs().format("YYYY-MM-DD HH:mm:ss");
  }, 1000);
});
onUnmounted(() => {
  stopAutoScroll();
  if (refreshTimer) clearInterval(refreshTimer);
  window.removeEventListener("resize", handleResize);
  removeUserPauseListeners();
  if (resumeTimer) clearTimeout(resumeTimer);
});
</script>

<style lang="scss" scoped>
.board-container {
  height: 100vh;
  width: 100vw;
  overflow: auto;
  position: relative;
  box-sizing: border-box;
  background: #f7f8fa;
  display: flex;
  flex-direction: column;
}

/* 头部悬浮 */
.board-header-row {
  position: sticky;
  top: 0;
  z-index: 10;
  background: #f7f8fa;
  display: flex;
  align-items: center;
  justify-content: space-between;
  margin-bottom: 0;
  width: 100%;
  padding: 20px 20px 8px 20px;
  box-sizing: border-box;
  border-bottom: 1px solid #eee;
}

/* 状态悬浮 */
.board-status {
  position: sticky;
  top: 64px;
  /* 头部高度+padding-bottom */
  z-index: 9;
  background: #f7f8fa;
  color: #666666;
  margin-bottom: 0;
  padding: 8px 20px 8px 20px;
  box-sizing: border-box;
  border-bottom: 1px solid #eee;
}

/* 让实时看板号等信息靠左 */
.board-header-info {
  display: flex;
  align-items: center;
  gap: 12px;
  color: #666;
}

/* 字段选择弹窗样式优化 */
.dropdown {
  position: relative;
}

.dropdown-btn {
  padding: 8px 22px;
  cursor: pointer;
  border: 1px solid #ccc;
  background: #fff;
  border-radius: 6px;
  transition: background 0.2s;
  font-size: 20px;
}

.dropdown-btn:hover {
  background: #f5f5f5;
}

.dropdown-menu {
  position: absolute;
  top: 110%;
  right: 0;
  background-color: white;
  border: 1px solid #ccc;
  box-shadow: 0 2px 5px rgba(0, 0, 0, 0.1);
  width: 320px;
  z-index: 1002;
  border-radius: 6px;
  padding: 10px 0;
}

.dropdown-item {
  display: block;
  padding: 14px 32px;
  cursor: pointer;
  user-select: none;
  width: 100%;
  box-sizing: border-box;
}

.dropdown-item:hover {
  background-color: #f0f0f0;
}

.dropdown-item input[type="checkbox"] {
  width: 20px;
  height: 20px;
  margin-right: 12px;
  vertical-align: middle;
}

.board-header {
  color: #666666;
  margin-bottom: 8px;
  display: flex;
  align-items: center;
  flex-wrap: wrap;
}

.board-num {
  color: #000;
  margin-left: 4px;
  margin-right: 56px;
}

.board-joined {
  margin-right: 48px;
  margin-left: 4px;
}

.board-date {
  margin-left: 0;
}

.board-online {
  color: #000;
  margin-left: 4px;
  margin-right: 48px;
}

.board-offline-names {
  color: #000;
  margin-left: 4px;
}

/* 卡片区域自适应滚动 */
.card-area-scroll {
  flex: 1 1 auto;
  min-height: 0;
  overflow-y: auto;
  overflow-x: hidden;
  padding: 24px 0 0 0;
  width: 100%;
  box-sizing: border-box;
  display: flex;
  flex-direction: column;
  align-items: center;
}

/* 卡片用flex布局，自动换行，行间距20px */
.card {
  padding: 0 12px;
  width: 100%;
  display: grid;
  grid-template-columns: repeat(auto-fill, minmax(286px, 1fr));
  gap: 20px 24px; // 行间距20px，列间距24px
  width: 100%;
  min-height: 0;
  box-sizing: border-box;
  justify-content: center;
}

.card-wrapper {
  width: 100%;
  display: flex;
  justify-content: center;
}

.card-item {
  width: 286px;
  // height: 243px;
  padding: 14px 16px 12px 16px;
  border: 1px solid #ebeef5;
  border-radius: 12px;
  background: #fff;
  box-sizing: border-box;
  display: flex;
  flex-direction: column;
  justify-content: flex-start;
  overflow: hidden;
}

.card-row {
  // overflow: hidden;
  // white-space: nowrap;
  // text-overflow: ellipsis;
  margin-bottom: 10px;
}

.card-title {
  // display: flex;
  // align-items: center;
  // justify-content: space-between;
  margin-bottom: 8px;
  color: #333;
  white-space: nowrap;
  overflow: hidden;
  text-overflow: ellipsis;
  width: 100%;
  background: red;
}

.card-nickname {
  font-weight: bold;
}
.card-label {
  color: #768895;
}
.card-name {
  font-weight: bold;
  color: #000;
  margin-right: 8px;
}
.card-use-time {
  color: #f8ac23;
  margin-left: 4px;
}
.card-divider {
  margin: 8px 0 !important;
}
.card-content {
  flex: 1 1 auto;
  display: flex;
  flex-direction: column;
  justify-content: space-evenly;
  min-height: 0;
  overflow: hidden;
}
</style>
